/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "modules/skottie/src/SkottiePriv.h"

#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/animator/Animator.h"
#include "modules/sksg/include/SkSGRenderNode.h"

namespace skottie::internal {
namespace {
class ForwardingPlaybackController final : public Animator {
public:
    ForwardingPlaybackController(sk_sp<skresources::ExternalTrackAsset> track, float in_point, float out_point,
        float fps)
        : fTrack(std::move(track)), fInPoint(in_point), fOutPoint(out_point), fFps(fps)
    {}

private:
    StateChanged onSeek(float t) override
    {
        // Adjust t relative to the track time (s).
        if (t < fInPoint || t > fOutPoint) {
            t = -1;
        } else {
            t = (t - fInPoint) / fFps;
        }

        fTrack->seek(t);

        // does not interact with the render tree.
        return false;
    }

    const sk_sp<skresources::ExternalTrackAsset> fTrack;
    const float fInPoint, fOutPoint, fFps;
};
} // namespace

sk_sp<sksg::RenderNode> AnimationBuilder::attachAudioLayer(const skjson::ObjectValue &jlayer,
    LayerInfo *layer_info) const
{
    const ScopedAssetRef audio_asset(this, jlayer);

    if (audio_asset) {
        const auto &jaudio = *audio_asset;
        const skjson::StringValue *name = jaudio["p"];
        const skjson::StringValue *path = jaudio["u"];
        const skjson::StringValue *id = jaudio["id"];

        if (name && path && id) {
            auto track = fResourceProvider->loadAudioAsset(path->begin(), name->begin(), id->begin());
            if (track) {
                fCurrentAnimatorScope->push_back(sk_make_sp<ForwardingPlaybackController>(std::move(track),
                    layer_info->fInPoint, layer_info->fOutPoint, fFrameRate));
            } else {
                this->log(Logger::Level::kWarning, nullptr, "Could not load audio asset '%s'.", name->begin());
            }
        }
    }

    // no render node, playback is controlled from the Animator tree.
    return nullptr;
}
} // namespace skottie::internal
